package com.dl.debugtools

import android.Manifest
import android.annotation.TargetApi
import android.app.AppOpsManager
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.content.FileProvider
import androidx.lifecycle.lifecycleScope
import com.dl.base.AppContext
import com.dl.base.appContext
import com.dl.base.ui.BaseActivity
import com.dl.base.utils.getIP
import com.dl.base.viewmodel.createViewModel
import com.dl.debugtools.databinding.ActivityMainBinding
import splitties.permissions.requestPermission
import java.io.File


class MainActivity : BaseActivity<ActivityMainBinding>() {
    override fun setContentView() = R.layout.activity_main
    private val viewModel by lazy { createViewModel(DebugViewModel::class.java) }

    override fun init(bundle: Bundle?) {
        viewBinding.but1.setOnClickListener {
            stopService(Intent(this, CommandService::class.java))
            startService(Intent(this, CommandService::class.java))
            Toast.makeText(appContext, "Debug Tools-Pro重启成功", Toast.LENGTH_SHORT).show()
        }
        viewBinding.but2.setOnClickListener {
            install()
        }
        viewBinding.httpUrl.setText(AppContext.url)
        viewBinding.webSocketUrl.setText(AppContext.webSocketUrl)

        viewBinding.deviceName.setText(DebugToolsPreferences.deviceName)
        viewBinding.deviceNameSubmit.setOnClickListener {
            val deviceName = viewBinding.deviceName.text.toString()
            if (deviceName.isNotEmpty()) {
                viewModel.setDeviceName(deviceName)
            }
        }
        viewBinding.serverUrlSubmit.setOnClickListener {
            AppContext.url = viewBinding.httpUrl.text.toString()
            AppContext.webSocketUrl = viewBinding.webSocketUrl.text.toString()
        }
        viewBinding.adb.setOnClickListener {
            val commandList = arrayOf(
                "setprop service.adb.tcp.port 5555",
                "stop adbd",
                "start adbd"
            )

            if (ShellUtils.exeCmdByRoot(*commandList)) {
                viewBinding.ip.text = "adb connect ${getIP(this)}:5555"
            } else {
                viewBinding.ip.text = "错误，该设备未ROOT"
            }
        }

        startService(Intent(this, CommandService::class.java))
        setInstallPermission()
        notificationPermission()
        lifecycleScope.launchWhenResumed {
            requestPermission(Manifest.permission.READ_PHONE_STATE)
            requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
        }
    }

    private fun install() {
        val intent = Intent(Intent.ACTION_VIEW)
        val apkFile = File(FileUtil.getDownloadInstallPath())
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            val uri = FileProvider.getUriForFile(
                this,
                "${packageName}.fileprovider",
                apkFile
            )
            intent.setDataAndType(uri, "application/vnd.android.package-archive")
        } else {
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")
        }
        startActivity(intent)
    }

    /**
     * 8.0以上系统设置安装未知来源权限
     */
    private fun setInstallPermission() {
        val haveInstallPermission: Boolean
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //先判断是否有安装未知来源应用的权限
            haveInstallPermission = packageManager.canRequestPackageInstalls()
            if (!haveInstallPermission) {
                //此方法需要API>=26才能使用
                toInstallPermissionSettingIntent()
                return
            }
        }
    }


    /**
     * 开启安装未知来源权限
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun toInstallPermissionSettingIntent() {
        val packageURI: Uri = Uri.parse("package:$packageName")
        val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
        startActivityForResult(intent, 1001)
    }

    private fun notificationPermission() {
        val enabled = isNotificationEnabled(this)
        if (!enabled) {
            val localIntent = Intent()
            localIntent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
            localIntent.putExtra("app_package", this.packageName)
            localIntent.putExtra("app_uid", this.applicationInfo.uid)
            this.startActivity(localIntent);
        }
    }


    @TargetApi(Build.VERSION_CODES.KITKAT)
    fun isNotificationEnabled(context: Context): Boolean {
        val CHECK_OP_NO_THROW = "checkOpNoThrow"
        val OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"
        val mAppOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val appInfo: ApplicationInfo = context.applicationInfo
        val pkg: String = context.applicationContext.packageName
        val uid = appInfo.uid
        var appOpsClass: Class<*>? = null
        try {
            appOpsClass = Class.forName(AppOpsManager::class.java.name)
            val checkOpNoThrowMethod = appOpsClass.getMethod(
                CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
                String::class.java
            )
            val opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION)
            val value = opPostNotificationValue.get(Int::class.java) as Int
            return checkOpNoThrowMethod.invoke(
                mAppOps,
                value,
                uid,
                pkg
            ) as Int == AppOpsManager.MODE_ALLOWED
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    }
}
